home *** CD-ROM | disk | FTP | other *** search
- // ____________________________________________________
- // | |
- // | Project: POWER VIEW INTERFACE |
- // | File: PVCALC.CPP |
- // | Compiler: WPP386 (10.6) |
- // | |
- // | Subject: Power View Calculator |
- // | |
- // | Author: Emil Dotchevski |
- // |____________________________________________________|
- //
- // E-mail: zajo@geocities.com
- // URL: http://www.geocities.com/SiliconValley/Bay/3577
-
- #define uses_math
- #define uses_stdio
- #define uses_string
- #define uses_calc
- #define uses_dc
- #define uses_desk
- #define uses_dialog
- #define uses_editor
- #define uses_icons
- #define uses_lines
- #define uses_system
-
- #include "PVuses.h"
-
- #define cm0 cmUSER00
- #define cm1 cmUSER01
- #define cm2 cmUSER02
- #define cm3 cmUSER03
- #define cm4 cmUSER04
- #define cm5 cmUSER05
- #define cm6 cmUSER06
- #define cm7 cmUSER07
- #define cm8 cmUSER08
- #define cm9 cmUSER09
- #define cmCLR cmUSER10
- #define cmBACK cmUSER11
- #define cmFLIP_SIGN cmUSER12
- #define cmPOINT cmUSER13
- #define cmPERCENT cmUSER14
- #define cmMUL cmUSER15
- #define cmDIV cmUSER16
- #define cmADD cmUSER17
- #define cmSUB cmUSER18
- #define cmEVAL cmUSER19
-
- #define csFIRST 0
- #define csVALID 1
- #define csERROR 2
-
- class Tcalc_display: public Titem
- {
- public:
- char status;
- char number[16];
- char sign;
- uint op;
- double operand;
- Tcalc_display( void );
- virtual void initialize( void );
- #ifndef HGR
- virtual void set_palette( void );
- #endif
- virtual void draw( void );
- void clear( void );
- void calc_command( uint command );
- boolean clip_cut( void );
- boolean clip_copy( void );
- boolean clip_paste( void );
-
- protected:
- virtual void get_focused( void );
- virtual void event_handler( Tevent &ev );
-
- private:
- void update_commands( void );
- void error( void );
- void set_display( double r );
- void get_display( double &r );
- void check_first( void );
- };
-
- class Tcalculator: public Tdialog
- {
- public:
- Tcalculator( void );
- virtual ~Tcalculator( void );
- virtual boolean valid( uint command );
-
- protected:
- virtual void set_palette( void );
-
- private:
- Tcalc_display *display;
- };
-
- static Tcalculator *calc_window = NULL;
-
- //Tcalculator publics:
-
- static Tbutton *btn( char *t, uint c )
- {
- Tbutton *b;
-
- b = button( t, c );
- b->shortcut = t[1];
- b->set_flags( ifSELECTABLE, 0 );
- return b;
- }
-
- Tcalculator::Tcalculator( void ):
- #ifdef CYR
- Tdialog( "èὬ│½á▓«░", 5, 3 )
- #else
- Tdialog( "Calculator", 5, 3 )
- #endif
- {
- set_flags( ifICONIZEABLE+ifSELECTABLE, 1 );
- set_state( isON_TOP, 1 );
- palette = wpTOOL;
- extern_dialog( this );
- vspacing( 1 ); hspace();
- display = NEW( Tcalc_display );
- put_item( display, display->xl, display->yl );
- hor();
- nl();
- btn( " |~C ", cmCLR )->shortcut = kDEL;
- btn( " ", cmBACK )->shortcut = kBS;
- btn( " % ", cmPERCENT );
- btn( " ± ", cmFLIP_SIGN )->shortcut = '_';
- nl();
- btn( " 7 ", cm7 );
- btn( " 8 ", cm8 );
- btn( " 9 ", cm9 );
- btn( " / ", cmDIV );
- nl();
- btn( " 4 ", cm4 );
- btn( " 5 ", cm5 );
- btn( " 6 ", cm6 );
- btn( " * ", cmMUL );
- nl();
- btn( " 1 ", cm1 );
- btn( " 2 ", cm2 );
- btn( " 3 ", cm3 );
- btn( " - ", cmSUB );
- nl();
- btn( " 0 ", cm0 );
- btn( " . ", cmPOINT );
- btn( " = ", cmEVAL )->shortcut = kENTER;
- btn( " + ", cmADD );
- display->set_state( isSELECTED, 1 );
- focus();
- xl_min = 0;
- resize( xl + 1, yl + 1 );
- grow_mode = gmDONT_GROW;
- ~commands;
- commands<<cmWIN_MOVE<<cmWIN_MINIMIZE<<cmWIN_CLOSE
- <<cmWIN_RESTORE<<cmWIN_ON_TOP;
- for( uint i = cmUSER00; i <= cmUSER99; i++ )
- commands<<i;
- }
-
- Tcalculator::~Tcalculator( void )
- {
- calc_window = NULL;
- }
-
- boolean Tcalculator::valid( uint command )
- {
- if( ( command < cm0 ) || ( command > cmEVAL ) )
- return Tdialog::valid( command );
- display->calc_command( command );
- return 0;
- }
-
- //Tcalculator protected:
-
- void Tcalculator::set_palette( void )
- {
- Tdialog::set_palette();
- shortcut_attr = (char) ( text_attr & 0x0F );
- }
-
- //Tcalc_display publics:
-
- Tcalc_display::Tcalc_display( void ):
- Titem( 18, 1 )
- {
- clear();
- }
-
- void Tcalc_display::initialize( void )
- {
- Titem::initialize();
- owner->put_in( NEW( Tline0( xl ) ), x, y + 1 );
- owner->put_in( NEW( Tline1( xl ) ), x, y - 1 );
- }
-
- #ifndef HGR
- void Tcalc_display::set_palette( void )
- {
- Titem::set_palette();
- if( !graph_flag )
- {
- text_attr = rolb( text_attr, 4 );
- bold_attr &= 0x0F;
- bold_attr |= (char) ( text_attr & 0xF0 );
- }
- }
- #endif
-
- void Tcalc_display::draw( void )
- {
- txtf( "%s|r%c |b%c%s|t%s", i_left_line, xl - strlen( number ) - 3, sign, number, i_right_line );
- }
-
- void Tcalc_display::calc_command( uint command )
- {
- double r;
- char *p;
-
- if( ( status == csERROR ) && ( command != cmCLR ) ) command = 0;
- switch( command )
- {
- case cm0:
- case cm1:
- case cm2:
- case cm3:
- case cm4:
- case cm5:
- case cm6:
- case cm7:
- case cm8:
- case cm9:
- check_first();
- if( strlen( number ) < 15 )
- {
- if( !strcmp( number, "0" ) ) *number = 0;
- p = strchr( number, 0 );
- *(p++) = (char) ( command - cm0 + '0' );
- *p = 0;
- }
- break;
- case cmPOINT:
- check_first();
- if( strchr( number, '.' ) == NULL ) strcat( number, "." );
- break;
- case cmBACK:
- check_first();
- if( strlen( number ) == 1 )
- strcpy( number, "0" );
- else
- *( strchr( number, 0 ) - 1 ) = 0;
- break;
- case cmFLIP_SIGN:
- if( sign == ' ' ) sign = '-'; else sign = ' ';
- break;
- case cmPERCENT:
- case cmMUL:
- case cmDIV:
- case cmADD:
- case cmSUB:
- case cmEVAL:
- if( status == csVALID )
- {
- status = csFIRST;
- get_display( r );
- if( command == cmPERCENT )
- switch( op )
- {
- case cmADD:
- case cmSUB:
- r = operand * r / 100; break;
- case cmMUL:
- case cmDIV:
- r = r / 100; break;
- }
- switch( op )
- {
- case cmADD:
- set_display( operand + r ); break;
- case cmSUB:
- set_display( operand - r ); break;
- case cmMUL:
- set_display( operand * r ); break;
- case cmDIV:
- if( r == 0 )
- error();
- else
- set_display( operand / r );
- }
- }
- op = command;
- get_display( operand );
- break;
- case cmCLR:
- clear();
- }
- redraw();
- update_commands();
- }
-
- boolean Tcalc_display::clip_cut( void )
- {
- if( !clip_copy() ) return 0;
- clear();
- redraw();
- return 1;
- }
-
- boolean Tcalc_display::clip_copy( void )
- {
- char buf[ sizeof( number ) + 1 ], *s;
-
- if( clipboard == NULL ) return 0;
- s = buf;
- if( sign == '-' ) *buf = '-', s++;
- strcpy( s, number );
- return clipboard->insert_string( s, 1 );
- }
-
- boolean Tcalc_display::clip_paste( void )
- {
- uint sel_len;
- char buf[ sizeof( number ) + 1 ], *end_ptr;
- double v;
-
- if( ( clipboard == NULL ) || ( clipboard->lines_selected() != 1 ) ) return 0;
- sel_len = clipboard->sel_end - clipboard->sel_start;
- if( !sel_len || ( sel_len >= sizeof( buf ) ) ) return 0;
- clipboard->get_text( buf, clipboard->sel_start, sel_len );
- buf[sel_len] = 0;
- v = strtod( buf, &end_ptr );
- if( ( v == HUGE_VAL ) || ( v == -HUGE_VAL ) || *end_ptr ) return 0;
- set_display( v );
- status = csVALID;
- redraw();
- return 1;
- }
-
- void Tcalc_display::clear( void )
- {
- status = csFIRST;
- strcpy( number, "0" );
- sign = ' ';
- op = cmEVAL;
- }
-
- //Tcalc_display protected:
-
- void Tcalc_display::get_focused( void )
- {
- Titem::get_focused();
- update_commands();
- }
-
- void Tcalc_display::event_handler( Tevent &ev )
- {
- Titem::event_handler( ev );
- switch( ev.code )
- {
- case evCOMMAND:
- switch( ev.CMD_CODE )
- {
- case cmCUT:
- clip_cut();
- break;
- case cmCOPY:
- clip_copy();
- break;
- case cmPASTE:
- clip_paste();
- break;
- case cmCLEAR:
- clear();
- redraw();
- break;
- default:
- return;
- }
- handled( ev );
- update_commands();
- break;
- case evKEY_PRESS:
- if( ev.ASCII == kESC ) put_command( owner, cmDONE );
- }
- }
-
- //Tcalc_display private:
-
- void Tcalc_display::update_commands( void )
- {
- boolean fl = ( clipboard != NULL ) && ( status != csERROR );
- cstate( cmPASTE, fl && ( clipboard->lines_selected() == 1 ) );
- cstate( cmCUT, fl );
- cstate( cmCOPY, fl );
- cstate( cmCLEAR, fl );
- }
-
- void Tcalc_display::error( void )
- {
- status = csERROR;
- strcpy( number, "error" );
- sign = ' ';
- }
-
- void Tcalc_display::set_display( double r )
- {
- char s[65];
- char *p;
- int i;
-
- sign = ' ';
- if( r < 0 ) sign = '-', r = -r;
- i = 10;
- do
- {
- sprintf( s, "%.*f", i, r );
- }
- while( ( --i > 0 ) && ( strlen( s ) > 15 ) );
- if( strlen( s ) > 15 )
- error();
- else
- {
- while( *s && ( *( p = strchr( s, 0 ) - 1 ) == '0' ) ) *p = 0;
- if( *s && ( *( p = strchr( s, 0 ) - 1 ) == '.' ) ) *p = 0;
- strcpy( number, s );
- }
- }
-
- void Tcalc_display::get_display( double &r )
- {
- char buf[19];
-
- buf[0] = sign;
- strcpy( buf+1, number );
- r = atof( buf );
- }
-
- void Tcalc_display::check_first( void )
- {
- if( status == csFIRST )
- {
- status = csVALID;
- strcpy( number, "0" );
- sign = ' ';
- }
- }
-
- void calculator( void )
- {
- if( calc_window != NULL )
- {
- calc_window->focus();
- message( calc_window, cmWIN_RESTORE );
- }
- else
- {
- _context( cxCALCULATOR );
- calc_window = NEW( Tcalculator );
- desktop->put_in( calc_window, desktop->xl - calc_window->xl - 2, 1 );
- }
- }
-
- void close_calculator( void )
- {
- if( calc_window != NULL ) DELETE( calc_window );
- }
-